﻿#include "Item.h"
#pragma execution_character_set("utf-8")

Item::Item(int _ItemEntry,Player* _Owner, int _Item_Guid)
{
	m_ModifyCount = 0;
	m_Entry = _ItemEntry;
	m_Guid = _Item_Guid;
	m_Owner = _Owner;
	m_IsBonding = false;
	m_BagSlot = 0;
	m_ItemStatus = STATUS_NONE;
	Create();
	for (int i = MAIN_ONE; i != SUB_THREE; i++)
	{
		PotentialMap[(ItemPotential)i] = 0;
	}
	scheduleUpdate();
}

Item::~Item()
{

}

void Item::DeleteFromDB()
{
	char msg[255];
	snprintf(msg, 255, "DELETE FROM inventory_instance WHERE guid = %d and slot = %d", GetGuid(), GetBagSlot());
	Database::GetInstance()->PExcude(CharacterDatabase, msg);

	removeFromParentAndCleanup(true);
}

std::string Item::GetItemTotalModifyValueString(ItemValue _ItemValue, int Number)
{
	std::string returnstr = "";
	switch (_ItemValue)
	{
	case Item_Value_None:
		return returnstr;
	case Item_Value_Mana:
		returnstr += "MaxMP : +";
		break;
	case Item_Value_Heath:
		returnstr += "MaxHP : +";
		break;
	case Item_Value_Str:
		returnstr += "力量 : +";
		break;
	case Item_Value_Dex:
		returnstr += "敏捷 : +";
		break;
	case Item_Value_Int:
		returnstr += "智力 : +";
		break;
	case Item_Value_Luk:
		returnstr += "运气 : +";
		break;
	case Item_Value_Att:
		returnstr += "攻击力 : +";
		break;
	case Item_Value_Magic_Att:
		returnstr += "魔法攻击力 : +";
		break;
	case Item_Value_Att_Defance:
		returnstr += "防御力 : +";
		break;
	case Item_Value_Magic_Defance:
		returnstr += "魔法防御力 : +";
		break;
	case Item_Value_MissChance:
		returnstr += "回避 : +";
		break;
	case Item_Value_JumpHigh:
		returnstr += "跳跃力 : +";
		break;
	case Item_Value_MoveSpeed:
		returnstr += "移动速度 : +";
		break;
	case Item_Value_BossDamage:
		returnstr += "BOSS战斗时伤害 : +";
		char msga[255];
		snprintf(msga, 255, "%d%\n", Number);
		returnstr += msga;
		return returnstr;
	case Item_Value_Defance_Ingnore:
		returnstr += "BOSS战斗时无视护甲 : +";
		char msgb[255];
		snprintf(msgb, 255, "%d%\n", Number);
		returnstr += msgb;
		return returnstr;


	default:
		return returnstr;
	}
	char msg[255];
	snprintf(msg, 255, "%d\n", Number);
	returnstr += msg;
	return returnstr;
}
std::string Item::GetItemEquipSlotString()
{
	std::string returnstring = "未知";
	switch (m_ItemBaseInfo.Item_Slot)
	{
	case RING_ZERO:
	case RING_ONE:
	case RING_TWO:
	case RING_THR:
	case RING_FOR:
	case RING_FIVE:
		returnstring = "戒指";
		break;
	case NECKLACE_ZERO:
	case NECKLACE_ONE:
		returnstring = "项链";
		break;
	case MAIN_HAND:
		returnstring = "主手";
		break;
	case BELT:
		returnstring = "腰带";
		break;
	case HEAD:
		returnstring = "头部";
		break;
	case FACE:
		returnstring = "脸饰";
		break;
	case EYE:
		returnstring = "眼饰";
		break;
	case JACKET:
		returnstring = "上衣";
		break;
	case PANTS:
		returnstring = "裤子";
		break;
	case SHOES:
		returnstring = "鞋子";
		break;
	case PACKET:
		returnstring = "口袋物品";
		break;
	case EAR:
		returnstring = "耳环";
		break;
	case SHOULDER:
		returnstring = "肩膀";
		break;
	case WRIST:
		returnstring = "手腕";
		break;
	case ROBOT:
		returnstring = "机器人";
		break;
	case ROBOT_HEART:
		returnstring = "机械心脏";
		break;
	case SOURCE:
		returnstring = "能源";
		break;
	case DADGE_ZERO:
		returnstring = "徽章";
		break;
	case DADGE_ONE:
		returnstring = "胸章";
		break;
	case OFF_HAND:
		returnstring = "副手";
		break;
	case BACK:
		returnstring = "背部";
		break;
	}
	return returnstring;
}

std::string Item::GetClassString(ClassID _Classid)
{
	switch (_Classid)
	{
	case BASE_NONE:
		return "新手";
	case BASE_WARRIOR:
		return "战士";
	case BASE_MAGIC:
		return "魔法师";
	case BASE_THIEF:
		return "盗贼";
	case BASE_ARCHER:
		return "弓箭手";
	default:
		return "未知";
	}
}

int Item::GetItemTotalModifyValue(ItemValue _ItemValue)
{
	if (m_ItemBaseInfo.ItemValues.find(_ItemValue) == m_ItemBaseInfo.ItemValues.end() && ItemModifyValue.find(_ItemValue) == ItemModifyValue.end())
		return 0;

	if (m_ItemBaseInfo.ItemValues.find(_ItemValue) != m_ItemBaseInfo.ItemValues.end() && ItemModifyValue.find(_ItemValue) != ItemModifyValue.end())
		return m_ItemBaseInfo.ItemValues[_ItemValue] + ItemModifyValue[_ItemValue];

	if (m_ItemBaseInfo.ItemValues.find(_ItemValue) != m_ItemBaseInfo.ItemValues.end())
		return m_ItemBaseInfo.ItemValues[_ItemValue];

	if (ItemModifyValue.find(_ItemValue) != ItemModifyValue.end())
		return ItemModifyValue[_ItemValue];
}

void Item::SaveBase()
{
	//														1		 2			3		4			5				6					7				8					9					19				11
	std::string msgbasea = "INSERT INTO inventory_instance(`guid`, `Owner`, `Entry`,`Bonding`,`ModifyCount`,`Main_Potential_1`,`Main_Potential_2`,`Main_Potential_3`,`Sub_Potential_1`,`Sub_Potential_2`,`Sub_Potential_3`) ";
	char msgbase[255];//			1  2  3  4  5  6  7  8  9  10 11
	snprintf(msgbase, 255, "VALUES(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d) ON DUPLICATE KEY UPDATE guid = %d;", m_Guid, m_Owner->GetGuid(), m_Entry, m_IsBonding, m_ModifyCount, PotentialMap[(ItemPotential)0], PotentialMap[(ItemPotential)1], PotentialMap[(ItemPotential)2], PotentialMap[(ItemPotential)3], PotentialMap[(ItemPotential)4], PotentialMap[(ItemPotential)5], m_Guid);
	//																										  1				2				3		4				5				6								7								8								9								19								11							12
	msgbasea += msgbase;
	Database::GetInstance()->PExcude(CharacterDatabase, msgbasea.c_str());
}

void Item::SaveSlot()
{
	char msg[255];
	snprintf(msg, 255, "UPDATE inventory_instance SET slot = %d WHERE guid = %d", m_BagSlot, m_Guid);
	Database::GetInstance()->PExcude(CharacterDatabase, msg);
}

void Item::SaveModify()
{
	std::string msg = "INSERT INTO inventory_instance(`Value_1`,`Value_Number_1`,`Value_2`,`Value_Number_2`,`Value_3`,`Value_Number_3`,`Value_4`,`Value_Number_4`,`Value_5`,`Value_Number_5`,`Value_6`,`Value_Number_6`,`Value_7`,`Value_Number_7`,`Value_8`,`Value_Number_8`,`Value_9`,`Value_Number_9`,`Value_10`,`Value_Number_10`) VALUES(";
	for (int i = Item_Value_None; i != Item_Value_Defance_Ingnore; i++)
	{
		char aaa[50];
		snprintf(aaa, 50, "%d", ItemModifyValue[(ItemValue)i]);
		msg += aaa;
		if (i < Item_Value_Defance_Ingnore - 1)
			msg += ",";
	}
	msg += ") ON DUPLICATE KEY UPDATE guid = ";
	char bbb[50];
	snprintf(bbb, 50, "%d", m_Guid);
	msg += bbb;
	msg += ";";
	log("%s", msg);
	Database::GetInstance()->PExcude(CharacterDatabase, msg.c_str());
}

void Item::SaveToDB()
{
	SaveBase();
	SaveModify();
	SaveSlot();
}

void Item::Create()
{
	m_ItemBaseInfo = Map_Scene::GetInstance()->GetItemTemplate(m_Entry);
	if (m_ItemBaseInfo.Entry)
	{
		char msg[255];
		snprintf(msg, 255, "ItemImage/%s.png", m_ItemBaseInfo.Image_Url.c_str());
		if (initWithFile(msg))
			autorelease();
		if (m_Guid)
		{
			LoadFromInventoryDB(m_Guid);
		}
		else
		{
			Result::Qurey result = Database::GetInstance()->GetResult(CharacterDatabase, "SELECT guid FROM inventory_instance");
			if (!result.empty())
			{
				Result::Qurey result = Database::GetInstance()->GetResult(CharacterDatabase, "SELECT max(guid) FROM inventory_instance");
				if (!result.empty())
				{
					Result::Qurey::iterator itr = result.begin();
					int tempguid = atoi(itr->second.at(0).c_str()) + 1;
					m_Guid = tempguid;
					SaveToDB();
				}
			}
			else
			{
				m_Guid = 1;
				SaveToDB();
			}
		}
	}
}

void Item::LoadFromInventoryDB(int _guid)
{//								0			1				2				3				4					5					6				7			8			9			10			11			 12			13			  14			15			16			17			18			19			  20		21			  22		23				24			25			26			27			  28
	std::string msg = "SELECT Bonding, ModifyCount, Main_Potential_1, Main_Potential_2, Main_Potential_3, Sub_Potential_1, Sub_Potential_2, Sub_Potential_3, Value_1, Value_Number_1, Value_2, Value_Number_2, Value_3, Value_Number_3, Value_4, Value_Number_4, Value_5, Value_Number_5, Value_6, Value_Number_6, Value_7, Value_Number_7, Value_8, Value_Number_8, Value_9, Value_Number_9, Value_10, Value_Number_10, slot FROM inventory_instance WHERE guid = ";
	char msga[50];
	snprintf(msga, 50, "%d;", _guid);
	msg += msga;

	Result::Qurey result = Database::GetInstance()->GetResult(CharacterDatabase, msg.c_str());
	if (!result.empty())
	{
		for (Result::Qurey::iterator itr = result.begin(); itr != result.end(); itr++)
		{
			m_IsBonding = atoi(itr->second.at(0).c_str());
			m_ModifyCount = atoi(itr->second.at(1).c_str());
			int potential_value = 3;
			for (int i = MAIN_ONE; i != SUB_THREE + 1; i++)
			{
				PotentialMap[(ItemPotential)i] = atoi(itr->second.at(potential_value).c_str());
				potential_value += 2;
			}
			m_BagSlot = atoi(itr->second.at(28).c_str());

			int m = 8;
			for (int i = 0; i != 10; i++)
			{
				ItemValue TempValueName = (ItemValue)atoi(itr->second.at(m).c_str());
				int TempValueNumber = atoi(itr->second.at(++m).c_str());
				ItemModifyValue[TempValueName] = TempValueNumber;
				m++;
			}
			switch (GetComeFrom())
			{
			case COMEFROM_NULL:
				break;
			case COMEFROM_BAG:
				AddToBag();
				break;
			case COMEFROM_EQUIP:
				AddToEquipUI();
				break;
			}
		}
	}
}

void Item::AddToEquipUI()
{
	if (Slot* pSlot = m_Owner->GetEquipBag()->GetSlot(m_BagSlot))
	{
		pSlot->SetItemGuid(m_Entry);
		pSlot->SetItem(this);
		setTag(pSlot->getTag() * 10);
		setPosition(pSlot->getContentSize().width / 2, pSlot->getContentSize().height / 2);
		pSlot->addChild(this);
	}
	else
	{
		log("Nullptr Slot From Item::AddToEquipUI()!");
	}
}

void Item::AddToBag()
{
	if (Slot* pSlot = m_Owner->GetBag()->GetSlot(m_BagSlot))
	{
		pSlot->SetItemGuid(m_Entry);
		pSlot->SetItem(this);
		setTag(pSlot->getTag() * 10);
		setPosition(pSlot->getContentSize().width / 2, pSlot->getContentSize().height / 2);
		pSlot->addChild(this);
	}
	else
	{
		log("Nullptr Slot From Item::AddToBag()!");
	}
}

ComeFrom Item::GetComeFrom()
{
	if (!GetBagSlot())
		return COMEFROM_NULL;

	int Tag = GetBagSlot();
	if (Tag > BAG_TAG && Tag <= BAG_SLOT_TAG_ENDED)
	{
		return COMEFROM_BAG;
	}
	if (Tag >= PLAYER_EQUIP_SLOT_START && Tag <= PLAYER_EQUIP_SLOT_END)
	{
		return COMEFROM_EQUIP;
	}

	return COMEFROM_NULL;
}

void Item::update(float diff)
{
	if (m_ItemStatus)
	{
		SaveToDB();
		m_ItemStatus = STATUS_NONE;
	}
}